import { defineStore } from 'pinia'
import dayjs from 'dayjs'
import { getCache, removeCache, setCache } from '@/utils/cache'
import { TOKEN_KEY, USER_INFO_KEY } from '@/enums/cacheEnum'
import { login, logout, refreshToken } from '@/services/api/auth'

const defaultTokenModel: ApiModels.base.TokenModel = {
  token: '',
  expiration: '2000-1-1',
  expiresIn: 0,
  refreshToken: '',
  type: 'Bearer',
}

interface AuthState {
  tokenModel: ApiModels.base.TokenModel
}

export const useAuthStore = defineStore({
  id: 'auth',
  state: (): AuthState => ({ tokenModel: { ...defaultTokenModel } }),
  getters: {
    getToken: state => state?.tokenModel?.token || '',
    isLogin: (state): boolean => state && !!state.tokenModel.token && dayjs().isBefore(state.tokenModel.expiration, 'second'),
  },
  actions: {
    initToken() {
      const data = getCache<ApiModels.base.TokenModel>(TOKEN_KEY) || { ...defaultTokenModel }
      this.tokenModel = { ...data }
    },
    setToken(data: ApiModels.base.TokenModel, expire?: number | null) {
      this.tokenModel = { ...data }
      setCache(TOKEN_KEY, data, expire)
    },
    /**
     * @description 登录
     */
    async login(params: LoginParams): Promise<ApiModels.base.TokenModel | undefined> {
      try {
        const { error, data } = await login(params)
        if (error)
          return Promise.reject(error)
        this.setToken(data || {})
        return Promise.resolve(data)
      }
      catch (err: any) {
        return Promise.reject(err)
      }
    },
    /**
     * @description 登出
     */
    async loginOut(): Promise<any> {
      try {
        const res = await logout()
        removeCache(TOKEN_KEY)
        removeCache(USER_INFO_KEY)
        return Promise.resolve(res)
      }
      catch (err: any) {
        return Promise.reject(err)
      }
    },
    /**
     * @description 刷新token
     */
    async refresh(): Promise<LoginModel> {
      try {
        const { error, data } = await refreshToken()
        if (error)
          return Promise.reject(error)
        this.setToken(data)
        return Promise.resolve(data)
      }
      catch (err: any) {
        return Promise.reject(err)
      }
    },
  },
})
